; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+f,+zknh -target-abi=lp64f \
; RUN:   | FileCheck %s --check-prefixes=CHECK,RV64I
; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zba,+zbb,+f,+zknh -target-abi=lp64f \
; RUN:   | FileCheck %s --check-prefixes=CHECK,RV64ZBB
; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zba,+zbb,+f,+zknh -target-abi=lp64f \
; RUN:   -riscv-disable-sextw-removal | FileCheck %s --check-prefix=NOREMOVAL

define void @test1(i32 signext %arg, i32 signext %arg1) nounwind {
; CHECK-LABEL: test1:
; CHECK:       # %bb.0: # %bb
; CHECK-NEXT:    addi sp, sp, -32
; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
; CHECK-NEXT:    mv s0, a1
; CHECK-NEXT:    sraw s1, a0, a1
; CHECK-NEXT:  .LBB0_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    mv a0, s1
; CHECK-NEXT:    call bar@plt
; CHECK-NEXT:    sllw s1, s1, s0
; CHECK-NEXT:    bnez a0, .LBB0_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
; CHECK-NEXT:    addi sp, sp, 32
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test1:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -32
; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    mv s0, a1
; NOREMOVAL-NEXT:    sraw s1, a0, a1
; NOREMOVAL-NEXT:  .LBB0_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a0, s1
; NOREMOVAL-NEXT:    call bar@plt
; NOREMOVAL-NEXT:    sllw s1, s1, s0
; NOREMOVAL-NEXT:    bnez a0, .LBB0_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 32
; NOREMOVAL-NEXT:    ret
bb:
  %i = ashr i32 %arg, %arg1
  br label %bb2

bb2:                                              ; preds = %bb2, %bb
  %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
  %i4 = tail call signext i32 @bar(i32 signext %i3)
  %i5 = shl i32 %i3, %arg1
  %i6 = icmp eq i32 %i4, 0
  br i1 %i6, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  ret void
}

declare signext i32 @bar(i32 signext)

; The load here was previously an aext load, but this has since been changed
; to a signext load allowing us to remove a sext.w before isel. Thus we get
; the same result with or without the sext.w removal pass.
; Test has been left for coverage purposes.
define signext i32 @test2(ptr %p, i32 signext %b) nounwind {
; RV64I-LABEL: test2:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lw a0, 0(a0)
; RV64I-NEXT:    li a2, 1
; RV64I-NEXT:    sllw a1, a2, a1
; RV64I-NEXT:    not a1, a1
; RV64I-NEXT:    and a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBB-LABEL: test2:
; RV64ZBB:       # %bb.0:
; RV64ZBB-NEXT:    lw a0, 0(a0)
; RV64ZBB-NEXT:    li a2, -2
; RV64ZBB-NEXT:    rolw a1, a2, a1
; RV64ZBB-NEXT:    and a0, a1, a0
; RV64ZBB-NEXT:    ret
;
; NOREMOVAL-LABEL: test2:
; NOREMOVAL:       # %bb.0:
; NOREMOVAL-NEXT:    lw a0, 0(a0)
; NOREMOVAL-NEXT:    li a2, -2
; NOREMOVAL-NEXT:    rolw a1, a2, a1
; NOREMOVAL-NEXT:    and a0, a1, a0
; NOREMOVAL-NEXT:    ret
  %a = load i32, ptr %p
  %shl = shl i32 1, %b
  %neg = xor i32 %shl, -1
  %and1 = and i32 %neg, %a
  ret i32 %and1
}

define signext i32 @test3(ptr %p, i32 signext %b) nounwind {
; RV64I-LABEL: test3:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lw a0, 0(a0)
; RV64I-NEXT:    li a2, 1
; RV64I-NEXT:    sllw a1, a2, a1
; RV64I-NEXT:    not a1, a1
; RV64I-NEXT:    or a0, a1, a0
; RV64I-NEXT:    ret
;
; RV64ZBB-LABEL: test3:
; RV64ZBB:       # %bb.0:
; RV64ZBB-NEXT:    lw a0, 0(a0)
; RV64ZBB-NEXT:    li a2, -2
; RV64ZBB-NEXT:    rolw a1, a2, a1
; RV64ZBB-NEXT:    or a0, a1, a0
; RV64ZBB-NEXT:    ret
;
; NOREMOVAL-LABEL: test3:
; NOREMOVAL:       # %bb.0:
; NOREMOVAL-NEXT:    lw a0, 0(a0)
; NOREMOVAL-NEXT:    li a2, -2
; NOREMOVAL-NEXT:    rolw a1, a2, a1
; NOREMOVAL-NEXT:    or a0, a1, a0
; NOREMOVAL-NEXT:    ret
  %a = load i32, ptr %p
  %shl = shl i32 1, %b
  %neg = xor i32 %shl, -1
  %and1 = or i32 %neg, %a
  ret i32 %and1
}

define signext i32 @test4(ptr %p, i32 signext %b) nounwind {
; RV64I-LABEL: test4:
; RV64I:       # %bb.0:
; RV64I-NEXT:    lw a0, 0(a0)
; RV64I-NEXT:    li a2, 1
; RV64I-NEXT:    sllw a1, a2, a1
; RV64I-NEXT:    xor a0, a1, a0
; RV64I-NEXT:    not a0, a0
; RV64I-NEXT:    ret
;
; RV64ZBB-LABEL: test4:
; RV64ZBB:       # %bb.0:
; RV64ZBB-NEXT:    lw a0, 0(a0)
; RV64ZBB-NEXT:    li a2, 1
; RV64ZBB-NEXT:    sllw a1, a2, a1
; RV64ZBB-NEXT:    xnor a0, a1, a0
; RV64ZBB-NEXT:    ret
;
; NOREMOVAL-LABEL: test4:
; NOREMOVAL:       # %bb.0:
; NOREMOVAL-NEXT:    lw a0, 0(a0)
; NOREMOVAL-NEXT:    li a2, 1
; NOREMOVAL-NEXT:    sllw a1, a2, a1
; NOREMOVAL-NEXT:    xnor a0, a1, a0
; NOREMOVAL-NEXT:    ret
  %a = load i32, ptr %p
  %shl = shl i32 1, %b
  %neg = xor i32 %shl, -1
  %and1 = xor i32 %neg, %a
  ret i32 %and1
}

; Make sure we don't put a sext.w before bar when using cpopw.
define void @test5(i32 signext %arg, i32 signext %arg1) nounwind {
; RV64I-LABEL: test5:
; RV64I:       # %bb.0: # %bb
; RV64I-NEXT:    addi sp, sp, -48
; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT:    sraw a0, a0, a1
; RV64I-NEXT:    lui a1, 349525
; RV64I-NEXT:    addiw s0, a1, 1365
; RV64I-NEXT:    lui a1, 209715
; RV64I-NEXT:    addiw s1, a1, 819
; RV64I-NEXT:    lui a1, 61681
; RV64I-NEXT:    addiw s2, a1, -241
; RV64I-NEXT:    lui a1, 4112
; RV64I-NEXT:    addiw s3, a1, 257
; RV64I-NEXT:  .LBB4_1: # %bb2
; RV64I-NEXT:    # =>This Inner Loop Header: Depth=1
; RV64I-NEXT:    call bar@plt
; RV64I-NEXT:    mv a1, a0
; RV64I-NEXT:    srli a0, a0, 1
; RV64I-NEXT:    and a0, a0, s0
; RV64I-NEXT:    sub a0, a1, a0
; RV64I-NEXT:    and a2, a0, s1
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, s1
; RV64I-NEXT:    add a0, a2, a0
; RV64I-NEXT:    srli a2, a0, 4
; RV64I-NEXT:    add a0, a0, a2
; RV64I-NEXT:    and a0, a0, s2
; RV64I-NEXT:    mul a0, a0, s3
; RV64I-NEXT:    srliw a0, a0, 24
; RV64I-NEXT:    bnez a1, .LBB4_1
; RV64I-NEXT:  # %bb.2: # %bb7
; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT:    addi sp, sp, 48
; RV64I-NEXT:    ret
;
; RV64ZBB-LABEL: test5:
; RV64ZBB:       # %bb.0: # %bb
; RV64ZBB-NEXT:    addi sp, sp, -16
; RV64ZBB-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; RV64ZBB-NEXT:    sraw a0, a0, a1
; RV64ZBB-NEXT:  .LBB4_1: # %bb2
; RV64ZBB-NEXT:    # =>This Inner Loop Header: Depth=1
; RV64ZBB-NEXT:    call bar@plt
; RV64ZBB-NEXT:    mv a1, a0
; RV64ZBB-NEXT:    cpopw a0, a0
; RV64ZBB-NEXT:    bnez a1, .LBB4_1
; RV64ZBB-NEXT:  # %bb.2: # %bb7
; RV64ZBB-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; RV64ZBB-NEXT:    addi sp, sp, 16
; RV64ZBB-NEXT:    ret
;
; NOREMOVAL-LABEL: test5:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -16
; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sraw a1, a0, a1
; NOREMOVAL-NEXT:  .LBB4_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a0, a1
; NOREMOVAL-NEXT:    call bar@plt
; NOREMOVAL-NEXT:    cpopw a1, a0
; NOREMOVAL-NEXT:    bnez a0, .LBB4_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 16
; NOREMOVAL-NEXT:    ret
bb:
  %i = ashr i32 %arg, %arg1
  br label %bb2

bb2:                                              ; preds = %bb2, %bb
  %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
  %i4 = tail call signext i32 @bar(i32 signext %i3)
  %i5 = tail call i32 @llvm.ctpop.i32(i32 %i4)
  %i6 = icmp eq i32 %i4, 0
  br i1 %i6, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  ret void
}

declare i32 @llvm.ctpop.i32(i32)

define void @test6(i32 signext %arg, i32 signext %arg1) nounwind {
; CHECK-LABEL: test6:
; CHECK:       # %bb.0: # %bb
; CHECK-NEXT:    addi sp, sp, -16
; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; CHECK-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
; CHECK-NEXT:    sraw a0, a0, a1
; CHECK-NEXT:    fmv.w.x fs0, zero
; CHECK-NEXT:  .LBB5_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    call baz@plt
; CHECK-NEXT:    feq.s a1, fa0, fs0
; CHECK-NEXT:    fcvt.w.s a0, fa0, rtz
; CHECK-NEXT:    beqz a1, .LBB5_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; CHECK-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
; CHECK-NEXT:    addi sp, sp, 16
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test6:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -16
; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
; NOREMOVAL-NEXT:    sraw a0, a0, a1
; NOREMOVAL-NEXT:    fmv.w.x fs0, zero
; NOREMOVAL-NEXT:  .LBB5_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    call baz@plt
; NOREMOVAL-NEXT:    feq.s a1, fa0, fs0
; NOREMOVAL-NEXT:    fcvt.w.s a0, fa0, rtz
; NOREMOVAL-NEXT:    beqz a1, .LBB5_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 16
; NOREMOVAL-NEXT:    ret
bb:
  %i = ashr i32 %arg, %arg1
  br label %bb2

bb2:                                              ; preds = %bb2, %bb
  %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
  %i4 = tail call float @baz(i32 signext %i3)
  %i5 = fptosi float %i4 to i32
  %i6 = fcmp oeq float %i4, zeroinitializer
  br i1 %i6, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  ret void
}
declare float @baz(i32 signext %i3)

define void @test7(i32 signext %arg, i32 signext %arg1) nounwind {
; RV64I-LABEL: test7:
; RV64I:       # %bb.0: # %bb
; RV64I-NEXT:    addi sp, sp, -48
; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
; RV64I-NEXT:    lui a2, %hi(.LCPI6_0)
; RV64I-NEXT:    ld s0, %lo(.LCPI6_0)(a2)
; RV64I-NEXT:    lui a2, %hi(.LCPI6_1)
; RV64I-NEXT:    ld s1, %lo(.LCPI6_1)(a2)
; RV64I-NEXT:    lui a2, %hi(.LCPI6_2)
; RV64I-NEXT:    ld s2, %lo(.LCPI6_2)(a2)
; RV64I-NEXT:    lui a2, %hi(.LCPI6_3)
; RV64I-NEXT:    ld s3, %lo(.LCPI6_3)(a2)
; RV64I-NEXT:    sraw a0, a0, a1
; RV64I-NEXT:  .LBB6_1: # %bb2
; RV64I-NEXT:    # =>This Inner Loop Header: Depth=1
; RV64I-NEXT:    call foo@plt
; RV64I-NEXT:    srli a1, a0, 1
; RV64I-NEXT:    and a1, a1, s0
; RV64I-NEXT:    sub a0, a0, a1
; RV64I-NEXT:    and a1, a0, s1
; RV64I-NEXT:    srli a0, a0, 2
; RV64I-NEXT:    and a0, a0, s1
; RV64I-NEXT:    add a0, a1, a0
; RV64I-NEXT:    srli a1, a0, 4
; RV64I-NEXT:    add a0, a0, a1
; RV64I-NEXT:    and a0, a0, s2
; RV64I-NEXT:    mul a0, a0, s3
; RV64I-NEXT:    srli a0, a0, 56
; RV64I-NEXT:    bnez a0, .LBB6_1
; RV64I-NEXT:  # %bb.2: # %bb7
; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
; RV64I-NEXT:    addi sp, sp, 48
; RV64I-NEXT:    ret
;
; RV64ZBB-LABEL: test7:
; RV64ZBB:       # %bb.0: # %bb
; RV64ZBB-NEXT:    addi sp, sp, -16
; RV64ZBB-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; RV64ZBB-NEXT:    sraw a0, a0, a1
; RV64ZBB-NEXT:  .LBB6_1: # %bb2
; RV64ZBB-NEXT:    # =>This Inner Loop Header: Depth=1
; RV64ZBB-NEXT:    call foo@plt
; RV64ZBB-NEXT:    cpop a0, a0
; RV64ZBB-NEXT:    bnez a0, .LBB6_1
; RV64ZBB-NEXT:  # %bb.2: # %bb7
; RV64ZBB-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; RV64ZBB-NEXT:    addi sp, sp, 16
; RV64ZBB-NEXT:    ret
;
; NOREMOVAL-LABEL: test7:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -16
; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sraw a0, a0, a1
; NOREMOVAL-NEXT:  .LBB6_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    call foo@plt
; NOREMOVAL-NEXT:    cpop a0, a0
; NOREMOVAL-NEXT:    bnez a0, .LBB6_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 16
; NOREMOVAL-NEXT:    ret
bb:
  %i = ashr i32 %arg, %arg1
  br label %bb2

bb2:                                              ; preds = %bb2, %bb
  %i3 = phi i32 [ %i, %bb ], [ %i6, %bb2 ]
  %i4 = tail call signext i64 @foo(i32 signext %i3)
  %i5 = tail call i64 @llvm.ctpop.i64(i64 %i4)
  %i6 = trunc i64 %i5 to i32
  %i7 = icmp eq i32 %i6, 0
  br i1 %i7, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  ret void
}

declare i64 @llvm.ctpop.i64(i64)

define void @test8(i32 signext %arg, i32 signext %arg1) nounwind {
; CHECK-LABEL: test8:
; CHECK:       # %bb.0: # %bb
; CHECK-NEXT:    addi sp, sp, -16
; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sraw a0, a0, a1
; CHECK-NEXT:  .LBB7_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    call foo@plt
; CHECK-NEXT:    ori a0, a0, -256
; CHECK-NEXT:    bnez a0, .LBB7_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; CHECK-NEXT:    addi sp, sp, 16
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test8:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -16
; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sraw a0, a0, a1
; NOREMOVAL-NEXT:  .LBB7_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    call foo@plt
; NOREMOVAL-NEXT:    ori a0, a0, -256
; NOREMOVAL-NEXT:    bnez a0, .LBB7_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 16
; NOREMOVAL-NEXT:    ret
bb:
  %i = ashr i32 %arg, %arg1
  br label %bb2

bb2:                                              ; preds = %bb2, %bb
  %i3 = phi i32 [ %i, %bb ], [ %i6, %bb2 ]
  %i4 = tail call signext i64 @foo(i32 signext %i3)
  %i5 = or i64 %i4, -256
  %i6 = trunc i64 %i5 to i32
  %i7 = icmp eq i32 %i6, 0
  br i1 %i7, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  ret void
}

declare i64 @foo(i32 signext)

define void @test9(i32 signext %arg, i32 signext %arg1) nounwind {
; CHECK-LABEL: test9:
; CHECK:       # %bb.0: # %bb
; CHECK-NEXT:    addi sp, sp, -16
; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sraw a0, a0, a1
; CHECK-NEXT:    li s0, 254
; CHECK-NEXT:  .LBB8_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    call bar@plt
; CHECK-NEXT:    mv a1, a0
; CHECK-NEXT:    slti a0, a0, 255
; CHECK-NEXT:    blt s0, a1, .LBB8_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; CHECK-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
; CHECK-NEXT:    addi sp, sp, 16
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test9:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -16
; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sraw a1, a0, a1
; NOREMOVAL-NEXT:    li s0, 254
; NOREMOVAL-NEXT:  .LBB8_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a0, a1
; NOREMOVAL-NEXT:    call bar@plt
; NOREMOVAL-NEXT:    slti a1, a0, 255
; NOREMOVAL-NEXT:    blt s0, a0, .LBB8_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 16
; NOREMOVAL-NEXT:    ret
bb:
  %i = ashr i32 %arg, %arg1
  br label %bb2

bb2:                                              ; preds = %bb2, %bb
  %i3 = phi i32 [ %i, %bb ], [ %i7, %bb2 ]
  %i4 = tail call signext i32 @bar(i32 signext %i3)
  %i5 = icmp slt i32 %i4, 255
  %i6 = sext i1 %i5 to i32
  %i7 = sub i32 0, %i6
  br i1 %i5, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  ret void
}

define void @test10(i32 signext %arg, i32 signext %arg1) nounwind {
; CHECK-LABEL: test10:
; CHECK:       # %bb.0: # %bb
; CHECK-NEXT:    addi sp, sp, -16
; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; CHECK-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
; CHECK-NEXT:    sraw a0, a0, a1
; CHECK-NEXT:    fmv.w.x fs0, zero
; CHECK-NEXT:  .LBB9_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    call baz@plt
; CHECK-NEXT:    feq.s a1, fa0, fs0
; CHECK-NEXT:    fmv.x.w a0, fa0
; CHECK-NEXT:    beqz a1, .LBB9_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; CHECK-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
; CHECK-NEXT:    addi sp, sp, 16
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test10:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -16
; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
; NOREMOVAL-NEXT:    sraw a0, a0, a1
; NOREMOVAL-NEXT:    fmv.w.x fs0, zero
; NOREMOVAL-NEXT:  .LBB9_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    call baz@plt
; NOREMOVAL-NEXT:    feq.s a1, fa0, fs0
; NOREMOVAL-NEXT:    fmv.x.w a0, fa0
; NOREMOVAL-NEXT:    beqz a1, .LBB9_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 16
; NOREMOVAL-NEXT:    ret
bb:
  %i = ashr i32 %arg, %arg1
  br label %bb2

bb2:                                              ; preds = %bb2, %bb
  %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
  %i4 = tail call float @baz(i32 signext %i3)
  %i5 = bitcast float %i4 to i32
  %i6 = fcmp oeq float %i4, zeroinitializer
  br i1 %i6, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  ret void
}

; simple test for forward-searching. (and 1234) only uses lower word of input
define signext i32 @test11(i64 %arg1, i64 %arg2, i64 %arg3)  {
; CHECK-LABEL: test11:
; CHECK:       # %bb.0: # %entry
; CHECK-NEXT:    addi a2, a2, -1
; CHECK-NEXT:    li a3, 256
; CHECK-NEXT:  .LBB10_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    andi a0, a0, 1234
; CHECK-NEXT:    addi a2, a2, 1
; CHECK-NEXT:    addw a0, a0, a1
; CHECK-NEXT:    bltu a2, a3, .LBB10_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test11:
; NOREMOVAL:       # %bb.0: # %entry
; NOREMOVAL-NEXT:    addi a2, a2, -1
; NOREMOVAL-NEXT:    li a3, 256
; NOREMOVAL-NEXT:  .LBB10_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    andi a0, a0, 1234
; NOREMOVAL-NEXT:    addi a2, a2, 1
; NOREMOVAL-NEXT:    add a0, a0, a1
; NOREMOVAL-NEXT:    bltu a2, a3, .LBB10_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    ret
entry:
  br label %bb2

bb2:                                              ; preds = %bb2, %entry
  %i1 = phi i64 [ %arg1, %entry ], [ %i5, %bb2 ]
  %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
  %i3 = add i64 %i2, 1
  %i4 = and i64 %i1, 1234
  %i5 = add i64 %i4, %arg2
  %i6 = icmp ugt i64 %i2, 255
  br i1 %i6, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  %i7 = trunc i64 %i5 to i32
  ret i32 %i7
}

; circular use-dependency and multiple transformations.
define signext i32 @test12(i64 %arg1, i64 %arg2, i64 %arg3)  {
; CHECK-LABEL: test12:
; CHECK:       # %bb.0: # %entry
; CHECK-NEXT:    addi a3, a2, -1
; CHECK-NEXT:    li a4, 256
; CHECK-NEXT:  .LBB11_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    xor a0, a0, a1
; CHECK-NEXT:    mulw a2, a0, a1
; CHECK-NEXT:    addw a0, a0, a2
; CHECK-NEXT:    and a2, a2, a0
; CHECK-NEXT:    addi a3, a3, 1
; CHECK-NEXT:    add a0, a2, a1
; CHECK-NEXT:    bltu a3, a4, .LBB11_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    mv a0, a2
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test12:
; NOREMOVAL:       # %bb.0: # %entry
; NOREMOVAL-NEXT:    addi a2, a2, -1
; NOREMOVAL-NEXT:    li a3, 256
; NOREMOVAL-NEXT:  .LBB11_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    xor a0, a0, a1
; NOREMOVAL-NEXT:    mul a4, a0, a1
; NOREMOVAL-NEXT:    add a0, a0, a4
; NOREMOVAL-NEXT:    and a4, a4, a0
; NOREMOVAL-NEXT:    addi a2, a2, 1
; NOREMOVAL-NEXT:    add a0, a4, a1
; NOREMOVAL-NEXT:    bltu a2, a3, .LBB11_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    sext.w a0, a4
; NOREMOVAL-NEXT:    ret
entry:
  br label %bb2

bb2:                                              ; preds = %bb2, %entry
  %i1 = phi i64 [ %arg1, %entry ], [ %i6, %bb2 ]
  %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
  %i3 = add i64 %i2, 1
  %i4 = xor i64 %i1, %arg2
  %i5 = mul i64 %i4, %arg2
  %i9 = add i64 %i4, %i5
  %i8 = and i64 %i5, %i9
  %i6 = add i64 %i8, %arg2
  %i7 = icmp ugt i64 %i2, 255
  br i1 %i7, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  %r = trunc i64 %i8 to i32
  ret i32 %r
}

; Not optimized. sdiv doesn't only use lower word
define signext i32 @test13(i64 %arg1, i64 %arg2, i64 %arg3)  {
; CHECK-LABEL: test13:
; CHECK:       # %bb.0: # %entry
; CHECK-NEXT:    addi a2, a2, -1
; CHECK-NEXT:    li a3, 256
; CHECK-NEXT:  .LBB12_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    div a0, a0, a1
; CHECK-NEXT:    addi a2, a2, 1
; CHECK-NEXT:    add a0, a0, a1
; CHECK-NEXT:    bltu a2, a3, .LBB12_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    sext.w a0, a0
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test13:
; NOREMOVAL:       # %bb.0: # %entry
; NOREMOVAL-NEXT:    addi a2, a2, -1
; NOREMOVAL-NEXT:    li a3, 256
; NOREMOVAL-NEXT:  .LBB12_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    div a0, a0, a1
; NOREMOVAL-NEXT:    addi a2, a2, 1
; NOREMOVAL-NEXT:    add a0, a0, a1
; NOREMOVAL-NEXT:    bltu a2, a3, .LBB12_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    ret
entry:
  br label %bb2

bb2:                                              ; preds = %bb2, %entry
  %i1 = phi i64 [ %arg1, %entry ], [ %i5, %bb2 ]
  %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
  %i3 = add i64 %i2, 1
  %i4 = sdiv i64 %i1, %arg2
  %i5 = add i64 %i4, %arg2
  %i6 = icmp ugt i64 %i2, 255
  br i1 %i6, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  %i8 = trunc i64 %i5 to i32
  ret i32 %i8
}


; int test14(int a, int n) {
;   for (int i = 1; i < n; ++i) {
;     if (a > 1000)
;       return -1;
;     a += i;
;   }
;
;   return a;
; }
;
; There should be no sext.w in the loop.
define signext i32 @test14(i32 signext %0, i32 signext %1) {
; CHECK-LABEL: test14:
; CHECK:       # %bb.0:
; CHECK-NEXT:    li a2, 2
; CHECK-NEXT:    blt a1, a2, .LBB13_4
; CHECK-NEXT:  # %bb.1: # %.preheader
; CHECK-NEXT:    li a2, 1
; CHECK-NEXT:    li a3, 1000
; CHECK-NEXT:  .LBB13_2: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    blt a3, a0, .LBB13_5
; CHECK-NEXT:  # %bb.3: # in Loop: Header=BB13_2 Depth=1
; CHECK-NEXT:    addw a0, a2, a0
; CHECK-NEXT:    addiw a2, a2, 1
; CHECK-NEXT:    blt a2, a1, .LBB13_2
; CHECK-NEXT:  .LBB13_4:
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB13_5:
; CHECK-NEXT:    li a0, -1
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test14:
; NOREMOVAL:       # %bb.0:
; NOREMOVAL-NEXT:    li a2, 2
; NOREMOVAL-NEXT:    blt a1, a2, .LBB13_4
; NOREMOVAL-NEXT:  # %bb.1: # %.preheader
; NOREMOVAL-NEXT:    li a2, 1
; NOREMOVAL-NEXT:    li a3, 1000
; NOREMOVAL-NEXT:  .LBB13_2: # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a4, a0
; NOREMOVAL-NEXT:    blt a3, a4, .LBB13_5
; NOREMOVAL-NEXT:  # %bb.3: # in Loop: Header=BB13_2 Depth=1
; NOREMOVAL-NEXT:    addw a0, a2, a0
; NOREMOVAL-NEXT:    addiw a2, a2, 1
; NOREMOVAL-NEXT:    blt a2, a1, .LBB13_2
; NOREMOVAL-NEXT:  .LBB13_4:
; NOREMOVAL-NEXT:    ret
; NOREMOVAL-NEXT:  .LBB13_5:
; NOREMOVAL-NEXT:    li a0, -1
; NOREMOVAL-NEXT:    ret
  %3 = icmp sgt i32 %1, 1
  br i1 %3, label %4, label %12

4:                                                ; preds = %2, %8
  %5 = phi i32 [ %10, %8 ], [ 1, %2 ]
  %6 = phi i32 [ %9, %8 ], [ %0, %2 ]
  %7 = icmp sgt i32 %6, 1000
  br i1 %7, label %12, label %8

8:                                                ; preds = %4
  %9 = add nsw i32 %5, %6
  %10 = add nuw nsw i32 %5, 1
  %11 = icmp slt i32 %10, %1
  br i1 %11, label %4, label %12

12:                                               ; preds = %8, %4, %2
  %13 = phi i32 [ %0, %2 ], [ -1, %4 ], [ %9, %8 ]
  ret i32 %13
}

; Same as test14 but the signext attribute is missing from the argument so we
; can't optimize out the sext.w.
define signext i32 @test14b(i32 %0, i32 signext %1) {
; CHECK-LABEL: test14b:
; CHECK:       # %bb.0:
; CHECK-NEXT:    li a2, 2
; CHECK-NEXT:    blt a1, a2, .LBB14_4
; CHECK-NEXT:  # %bb.1: # %.preheader
; CHECK-NEXT:    li a2, 1
; CHECK-NEXT:    li a3, 1000
; CHECK-NEXT:  .LBB14_2: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    sext.w a4, a0
; CHECK-NEXT:    blt a3, a4, .LBB14_5
; CHECK-NEXT:  # %bb.3: # in Loop: Header=BB14_2 Depth=1
; CHECK-NEXT:    add a0, a2, a0
; CHECK-NEXT:    addiw a2, a2, 1
; CHECK-NEXT:    blt a2, a1, .LBB14_2
; CHECK-NEXT:  .LBB14_4:
; CHECK-NEXT:    sext.w a0, a0
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB14_5:
; CHECK-NEXT:    li a0, -1
; CHECK-NEXT:    sext.w a0, a0
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test14b:
; NOREMOVAL:       # %bb.0:
; NOREMOVAL-NEXT:    li a2, 2
; NOREMOVAL-NEXT:    blt a1, a2, .LBB14_4
; NOREMOVAL-NEXT:  # %bb.1: # %.preheader
; NOREMOVAL-NEXT:    li a2, 1
; NOREMOVAL-NEXT:    li a3, 1000
; NOREMOVAL-NEXT:  .LBB14_2: # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a4, a0
; NOREMOVAL-NEXT:    blt a3, a4, .LBB14_5
; NOREMOVAL-NEXT:  # %bb.3: # in Loop: Header=BB14_2 Depth=1
; NOREMOVAL-NEXT:    add a0, a2, a0
; NOREMOVAL-NEXT:    addiw a2, a2, 1
; NOREMOVAL-NEXT:    blt a2, a1, .LBB14_2
; NOREMOVAL-NEXT:  .LBB14_4:
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    ret
; NOREMOVAL-NEXT:  .LBB14_5:
; NOREMOVAL-NEXT:    li a0, -1
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    ret
  %3 = icmp sgt i32 %1, 1
  br i1 %3, label %4, label %12

4:                                                ; preds = %2, %8
  %5 = phi i32 [ %10, %8 ], [ 1, %2 ]
  %6 = phi i32 [ %9, %8 ], [ %0, %2 ]
  %7 = icmp sgt i32 %6, 1000
  br i1 %7, label %12, label %8

8:                                                ; preds = %4
  %9 = add nsw i32 %5, %6
  %10 = add nuw nsw i32 %5, 1
  %11 = icmp slt i32 %10, %1
  br i1 %11, label %4, label %12

12:                                               ; preds = %8, %4, %2
  %13 = phi i32 [ %0, %2 ], [ -1, %4 ], [ %9, %8 ]
  ret i32 %13
}

; Same as test14, but the argument is zero extended instead of sign extended so
; we can't optimize it.
define signext i32 @test14c(i32 zeroext %0, i32 signext %1) {
; CHECK-LABEL: test14c:
; CHECK:       # %bb.0:
; CHECK-NEXT:    li a2, 2
; CHECK-NEXT:    blt a1, a2, .LBB15_4
; CHECK-NEXT:  # %bb.1: # %.preheader
; CHECK-NEXT:    li a2, 1
; CHECK-NEXT:    li a3, 1000
; CHECK-NEXT:  .LBB15_2: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    sext.w a4, a0
; CHECK-NEXT:    blt a3, a4, .LBB15_5
; CHECK-NEXT:  # %bb.3: # in Loop: Header=BB15_2 Depth=1
; CHECK-NEXT:    add a0, a2, a0
; CHECK-NEXT:    addiw a2, a2, 1
; CHECK-NEXT:    blt a2, a1, .LBB15_2
; CHECK-NEXT:  .LBB15_4:
; CHECK-NEXT:    sext.w a0, a0
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB15_5:
; CHECK-NEXT:    li a0, -1
; CHECK-NEXT:    sext.w a0, a0
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test14c:
; NOREMOVAL:       # %bb.0:
; NOREMOVAL-NEXT:    li a2, 2
; NOREMOVAL-NEXT:    blt a1, a2, .LBB15_4
; NOREMOVAL-NEXT:  # %bb.1: # %.preheader
; NOREMOVAL-NEXT:    li a2, 1
; NOREMOVAL-NEXT:    li a3, 1000
; NOREMOVAL-NEXT:  .LBB15_2: # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a4, a0
; NOREMOVAL-NEXT:    blt a3, a4, .LBB15_5
; NOREMOVAL-NEXT:  # %bb.3: # in Loop: Header=BB15_2 Depth=1
; NOREMOVAL-NEXT:    add a0, a2, a0
; NOREMOVAL-NEXT:    addiw a2, a2, 1
; NOREMOVAL-NEXT:    blt a2, a1, .LBB15_2
; NOREMOVAL-NEXT:  .LBB15_4:
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    ret
; NOREMOVAL-NEXT:  .LBB15_5:
; NOREMOVAL-NEXT:    li a0, -1
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    ret
  %3 = icmp sgt i32 %1, 1
  br i1 %3, label %4, label %12

4:                                                ; preds = %2, %8
  %5 = phi i32 [ %10, %8 ], [ 1, %2 ]
  %6 = phi i32 [ %9, %8 ], [ %0, %2 ]
  %7 = icmp sgt i32 %6, 1000
  br i1 %7, label %12, label %8

8:                                                ; preds = %4
  %9 = add nsw i32 %5, %6
  %10 = add nuw nsw i32 %5, 1
  %11 = icmp slt i32 %10, %1
  br i1 %11, label %4, label %12

12:                                               ; preds = %8, %4, %2
  %13 = phi i32 [ %0, %2 ], [ -1, %4 ], [ %9, %8 ]
  ret i32 %13
}

; Same as test14 but the argument is zero extended from i31. Since bits 63:31
; are zero, this counts as an i32 sign extend so we can optimize it.
define signext i32 @test14d(i31 zeroext %0, i32 signext %1) {
; CHECK-LABEL: test14d:
; CHECK:       # %bb.0:
; CHECK-NEXT:    li a2, 2
; CHECK-NEXT:    blt a1, a2, .LBB16_4
; CHECK-NEXT:  # %bb.1: # %.preheader
; CHECK-NEXT:    li a2, 1
; CHECK-NEXT:    li a3, 1000
; CHECK-NEXT:  .LBB16_2: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    blt a3, a0, .LBB16_5
; CHECK-NEXT:  # %bb.3: # in Loop: Header=BB16_2 Depth=1
; CHECK-NEXT:    addw a0, a2, a0
; CHECK-NEXT:    addiw a2, a2, 1
; CHECK-NEXT:    blt a2, a1, .LBB16_2
; CHECK-NEXT:  .LBB16_4:
; CHECK-NEXT:    ret
; CHECK-NEXT:  .LBB16_5:
; CHECK-NEXT:    li a0, -1
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test14d:
; NOREMOVAL:       # %bb.0:
; NOREMOVAL-NEXT:    li a2, 2
; NOREMOVAL-NEXT:    blt a1, a2, .LBB16_4
; NOREMOVAL-NEXT:  # %bb.1: # %.preheader
; NOREMOVAL-NEXT:    li a2, 1
; NOREMOVAL-NEXT:    li a3, 1000
; NOREMOVAL-NEXT:  .LBB16_2: # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a4, a0
; NOREMOVAL-NEXT:    blt a3, a4, .LBB16_5
; NOREMOVAL-NEXT:  # %bb.3: # in Loop: Header=BB16_2 Depth=1
; NOREMOVAL-NEXT:    addw a0, a2, a0
; NOREMOVAL-NEXT:    addiw a2, a2, 1
; NOREMOVAL-NEXT:    blt a2, a1, .LBB16_2
; NOREMOVAL-NEXT:  .LBB16_4:
; NOREMOVAL-NEXT:    ret
; NOREMOVAL-NEXT:  .LBB16_5:
; NOREMOVAL-NEXT:    li a0, -1
; NOREMOVAL-NEXT:    ret
  %zext = zext i31 %0 to i32
  %3 = icmp sgt i32 %1, 1
  br i1 %3, label %4, label %12

4:                                                ; preds = %2, %8
  %5 = phi i32 [ %10, %8 ], [ 1, %2 ]
  %6 = phi i32 [ %9, %8 ], [ %zext, %2 ]
  %7 = icmp sgt i32 %6, 1000
  br i1 %7, label %12, label %8

8:                                                ; preds = %4
  %9 = add nsw i32 %5, %6
  %10 = add nuw nsw i32 %5, 1
  %11 = icmp slt i32 %10, %1
  br i1 %11, label %4, label %12

12:                                               ; preds = %8, %4, %2
  %13 = phi i32 [ %zext, %2 ], [ -1, %4 ], [ %9, %8 ]
  ret i32 %13
}

define signext i32 @test15(i64 %arg1, i64 %arg2, i64 %arg3, ptr %arg4)  {
; CHECK-LABEL: test15:
; CHECK:       # %bb.0: # %entry
; CHECK-NEXT:    addi a2, a2, -1
; CHECK-NEXT:    li a4, 256
; CHECK-NEXT:  .LBB17_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    andi a0, a0, 1234
; CHECK-NEXT:    addw a0, a0, a1
; CHECK-NEXT:    addi a2, a2, 1
; CHECK-NEXT:    sw a0, 0(a3)
; CHECK-NEXT:    bltu a2, a4, .LBB17_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test15:
; NOREMOVAL:       # %bb.0: # %entry
; NOREMOVAL-NEXT:    addi a2, a2, -1
; NOREMOVAL-NEXT:    li a4, 256
; NOREMOVAL-NEXT:  .LBB17_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    andi a0, a0, 1234
; NOREMOVAL-NEXT:    add a0, a0, a1
; NOREMOVAL-NEXT:    addi a2, a2, 1
; NOREMOVAL-NEXT:    sw a0, 0(a3)
; NOREMOVAL-NEXT:    bltu a2, a4, .LBB17_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    ret
entry:
  br label %bb2

bb2:                                              ; preds = %bb2, %entry
  %i1 = phi i64 [ %arg1, %entry ], [ %i5, %bb2 ]
  %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
  %i3 = add i64 %i2, 1
  %i4 = and i64 %i1, 1234
  %i5 = add i64 %i4, %arg2
  %i8 = trunc i64 %i5 to i32
  store i32 %i8, ptr %arg4
  %i6 = icmp ugt i64 %i2, 255
  br i1 %i6, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  %i7 = trunc i64 %i5 to i32
  ret i32 %i7
}

; This test previously removed a sext.w without converting a slli to slliw.
define signext i32 @bug(i32 signext %x) {
; CHECK-LABEL: bug:
; CHECK:       # %bb.0: # %entry
; CHECK-NEXT:    beqz a0, .LBB18_11
; CHECK-NEXT:  # %bb.1: # %if.end
; CHECK-NEXT:    srliw a1, a0, 16
; CHECK-NEXT:    beqz a1, .LBB18_3
; CHECK-NEXT:  # %bb.2: # %if.end
; CHECK-NEXT:    li a1, 32
; CHECK-NEXT:    j .LBB18_4
; CHECK-NEXT:  .LBB18_3:
; CHECK-NEXT:    slliw a0, a0, 16
; CHECK-NEXT:    li a1, 16
; CHECK-NEXT:  .LBB18_4: # %if.end
; CHECK-NEXT:    srliw a3, a0, 24
; CHECK-NEXT:    snez a2, a3
; CHECK-NEXT:    bnez a3, .LBB18_6
; CHECK-NEXT:  # %bb.5:
; CHECK-NEXT:    slliw a0, a0, 8
; CHECK-NEXT:  .LBB18_6: # %if.end
; CHECK-NEXT:    addiw a2, a2, -1
; CHECK-NEXT:    andi a2, a2, -8
; CHECK-NEXT:    add a1, a1, a2
; CHECK-NEXT:    srliw a3, a0, 28
; CHECK-NEXT:    snez a2, a3
; CHECK-NEXT:    bnez a3, .LBB18_8
; CHECK-NEXT:  # %bb.7:
; CHECK-NEXT:    slliw a0, a0, 4
; CHECK-NEXT:  .LBB18_8: # %if.end
; CHECK-NEXT:    addiw a2, a2, -1
; CHECK-NEXT:    andi a2, a2, -4
; CHECK-NEXT:    add a1, a1, a2
; CHECK-NEXT:    srliw a3, a0, 30
; CHECK-NEXT:    snez a2, a3
; CHECK-NEXT:    bnez a3, .LBB18_10
; CHECK-NEXT:  # %bb.9:
; CHECK-NEXT:    slliw a0, a0, 2
; CHECK-NEXT:  .LBB18_10: # %if.end
; CHECK-NEXT:    addiw a2, a2, -1
; CHECK-NEXT:    andi a2, a2, -2
; CHECK-NEXT:    not a0, a0
; CHECK-NEXT:    srli a0, a0, 31
; CHECK-NEXT:    add a0, a2, a0
; CHECK-NEXT:    addw a0, a1, a0
; CHECK-NEXT:  .LBB18_11: # %cleanup
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: bug:
; NOREMOVAL:       # %bb.0: # %entry
; NOREMOVAL-NEXT:    beqz a0, .LBB18_11
; NOREMOVAL-NEXT:  # %bb.1: # %if.end
; NOREMOVAL-NEXT:    srliw a1, a0, 16
; NOREMOVAL-NEXT:    beqz a1, .LBB18_3
; NOREMOVAL-NEXT:  # %bb.2: # %if.end
; NOREMOVAL-NEXT:    li a1, 32
; NOREMOVAL-NEXT:    j .LBB18_4
; NOREMOVAL-NEXT:  .LBB18_3:
; NOREMOVAL-NEXT:    slli a0, a0, 16
; NOREMOVAL-NEXT:    li a1, 16
; NOREMOVAL-NEXT:  .LBB18_4: # %if.end
; NOREMOVAL-NEXT:    srliw a3, a0, 24
; NOREMOVAL-NEXT:    snez a2, a3
; NOREMOVAL-NEXT:    bnez a3, .LBB18_6
; NOREMOVAL-NEXT:  # %bb.5:
; NOREMOVAL-NEXT:    slli a0, a0, 8
; NOREMOVAL-NEXT:  .LBB18_6: # %if.end
; NOREMOVAL-NEXT:    addiw a2, a2, -1
; NOREMOVAL-NEXT:    andi a2, a2, -8
; NOREMOVAL-NEXT:    add a1, a1, a2
; NOREMOVAL-NEXT:    srliw a3, a0, 28
; NOREMOVAL-NEXT:    snez a2, a3
; NOREMOVAL-NEXT:    bnez a3, .LBB18_8
; NOREMOVAL-NEXT:  # %bb.7:
; NOREMOVAL-NEXT:    slli a0, a0, 4
; NOREMOVAL-NEXT:  .LBB18_8: # %if.end
; NOREMOVAL-NEXT:    addiw a2, a2, -1
; NOREMOVAL-NEXT:    andi a2, a2, -4
; NOREMOVAL-NEXT:    add a1, a1, a2
; NOREMOVAL-NEXT:    srliw a3, a0, 30
; NOREMOVAL-NEXT:    snez a2, a3
; NOREMOVAL-NEXT:    bnez a3, .LBB18_10
; NOREMOVAL-NEXT:  # %bb.9:
; NOREMOVAL-NEXT:    slli a0, a0, 2
; NOREMOVAL-NEXT:  .LBB18_10: # %if.end
; NOREMOVAL-NEXT:    sext.w a0, a0
; NOREMOVAL-NEXT:    addiw a2, a2, -1
; NOREMOVAL-NEXT:    andi a2, a2, -2
; NOREMOVAL-NEXT:    not a0, a0
; NOREMOVAL-NEXT:    srli a0, a0, 31
; NOREMOVAL-NEXT:    add a0, a2, a0
; NOREMOVAL-NEXT:    addw a0, a1, a0
; NOREMOVAL-NEXT:  .LBB18_11: # %cleanup
; NOREMOVAL-NEXT:    ret
entry:
  %tobool.not = icmp eq i32 %x, 0
  br i1 %tobool.not, label %cleanup, label %if.end

if.end:                                           ; preds = %entry
  %tobool1.not = icmp ult i32 %x, 65536
  %shl = shl i32 %x, 16
  %spec.select = select i1 %tobool1.not, i32 %shl, i32 %x
  %spec.select43 = select i1 %tobool1.not, i32 16, i32 32
  %tobool5.not = icmp ult i32 %spec.select, 16777216
  %shl7 = shl i32 %spec.select, 8
  %sub8 = add nsw i32 %spec.select43, -8
  %x.addr.1 = select i1 %tobool5.not, i32 %shl7, i32 %spec.select
  %r.1 = select i1 %tobool5.not, i32 %sub8, i32 %spec.select43
  %tobool11.not = icmp ult i32 %x.addr.1, 268435456
  %shl13 = shl i32 %x.addr.1, 4
  %sub14 = add nsw i32 %r.1, -4
  %x.addr.2 = select i1 %tobool11.not, i32 %shl13, i32 %x.addr.1
  %r.2 = select i1 %tobool11.not, i32 %sub14, i32 %r.1
  %tobool17.not = icmp ult i32 %x.addr.2, 1073741824
  %shl19 = shl i32 %x.addr.2, 2
  %sub20 = add nsw i32 %r.2, -2
  %x.addr.3 = select i1 %tobool17.not, i32 %shl19, i32 %x.addr.2
  %r.3 = select i1 %tobool17.not, i32 %sub20, i32 %r.2
  %x.addr.3.lobit = ashr i32 %x.addr.3, 31
  %x.addr.3.lobit.not = xor i32 %x.addr.3.lobit, -1
  %r.4 = add nsw i32 %r.3, %x.addr.3.lobit.not
  br label %cleanup

cleanup:                                          ; preds = %entry, %if.end
  %retval.0 = phi i32 [ %r.4, %if.end ], [ 0, %entry ]
  ret i32 %retval.0
}

define void @test16(i32 signext %arg, i32 signext %arg1) nounwind {
; CHECK-LABEL: test16:
; CHECK:       # %bb.0: # %bb
; CHECK-NEXT:    addi sp, sp, -32
; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
; CHECK-NEXT:    mv s0, a1
; CHECK-NEXT:    call bar@plt
; CHECK-NEXT:    mv s1, a0
; CHECK-NEXT:  .LBB19_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    mv a0, s1
; CHECK-NEXT:    call bar@plt
; CHECK-NEXT:    sllw s1, s1, s0
; CHECK-NEXT:    bnez a0, .LBB19_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
; CHECK-NEXT:    addi sp, sp, 32
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test16:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -32
; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    mv s0, a1
; NOREMOVAL-NEXT:    call bar@plt
; NOREMOVAL-NEXT:    mv s1, a0
; NOREMOVAL-NEXT:  .LBB19_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a0, s1
; NOREMOVAL-NEXT:    call bar@plt
; NOREMOVAL-NEXT:    sllw s1, s1, s0
; NOREMOVAL-NEXT:    bnez a0, .LBB19_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 32
; NOREMOVAL-NEXT:    ret
bb:
  %i = call signext i32 @bar(i32 signext %arg)
  br label %bb2

bb2:                                              ; preds = %bb2, %bb
  %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
  %i4 = tail call signext i32 @bar(i32 signext %i3)
  %i5 = shl i32 %i3, %arg1
  %i6 = icmp eq i32 %i4, 0
  br i1 %i6, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  ret void
}

define void @test17(i32 signext %arg, i32 signext %arg1) nounwind {
; CHECK-LABEL: test17:
; CHECK:       # %bb.0: # %bb
; CHECK-NEXT:    addi sp, sp, -32
; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
; CHECK-NEXT:    mv s0, a1
; CHECK-NEXT:    call bat@plt
; CHECK-NEXT:    mv s1, a0
; CHECK-NEXT:  .LBB20_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    mv a0, s1
; CHECK-NEXT:    call bar@plt
; CHECK-NEXT:    sllw s1, s1, s0
; CHECK-NEXT:    bnez a0, .LBB20_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
; CHECK-NEXT:    addi sp, sp, 32
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test17:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -32
; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    mv s0, a1
; NOREMOVAL-NEXT:    call bat@plt
; NOREMOVAL-NEXT:    mv s1, a0
; NOREMOVAL-NEXT:  .LBB20_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a0, s1
; NOREMOVAL-NEXT:    call bar@plt
; NOREMOVAL-NEXT:    sllw s1, s1, s0
; NOREMOVAL-NEXT:    bnez a0, .LBB20_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 32
; NOREMOVAL-NEXT:    ret
bb:
  %i = call zeroext i16 @bat(i32 signext %arg)
  %zext = zext i16 %i to i32
  br label %bb2

bb2:                                              ; preds = %bb2, %bb
  %i3 = phi i32 [ %zext, %bb ], [ %i5, %bb2 ]
  %i4 = tail call signext i32 @bar(i32 signext %i3)
  %i5 = shl i32 %i3, %arg1
  %i6 = icmp eq i32 %i4, 0
  br i1 %i6, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  ret void
}
declare zeroext i16 @bat(i32 signext)

define void @test18(i32 signext %arg, i32 signext %arg1) nounwind {
; CHECK-LABEL: test18:
; CHECK:       # %bb.0: # %bb
; CHECK-NEXT:    addi sp, sp, -32
; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
; CHECK-NEXT:    mv s0, a1
; CHECK-NEXT:    sha256sig0 s1, a1
; CHECK-NEXT:  .LBB21_1: # %bb2
; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
; CHECK-NEXT:    mv a0, s1
; CHECK-NEXT:    call bar@plt
; CHECK-NEXT:    sllw s1, s1, s0
; CHECK-NEXT:    bnez a0, .LBB21_1
; CHECK-NEXT:  # %bb.2: # %bb7
; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
; CHECK-NEXT:    addi sp, sp, 32
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test18:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -32
; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    mv s0, a1
; NOREMOVAL-NEXT:    sha256sig0 s1, a1
; NOREMOVAL-NEXT:  .LBB21_1: # %bb2
; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
; NOREMOVAL-NEXT:    sext.w a0, s1
; NOREMOVAL-NEXT:    call bar@plt
; NOREMOVAL-NEXT:    sllw s1, s1, s0
; NOREMOVAL-NEXT:    bnez a0, .LBB21_1
; NOREMOVAL-NEXT:  # %bb.2: # %bb7
; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 32
; NOREMOVAL-NEXT:    ret
bb:
  %sext = sext i32 %arg1 to i64
  %i = call i64 @llvm.riscv.sha256sig0.i64(i64 %sext)
  %trunc = trunc i64 %i to i32
  br label %bb2

bb2:                                              ; preds = %bb2, %bb
  %i3 = phi i32 [ %trunc, %bb ], [ %i5, %bb2 ]
  %i4 = tail call signext i32 @bar(i32 signext %i3)
  %i5 = shl i32 %i3, %arg1
  %i6 = icmp eq i32 %i4, 0
  br i1 %i6, label %bb7, label %bb2

bb7:                                              ; preds = %bb2
  ret void
}
declare i64 @llvm.riscv.sha256sig0.i64(i64)

; The type promotion of %7 forms a sext_inreg, but %7 and %6 are combined to
; form a sh2add. This leaves behind a sext.w that isn't needed.
define signext i32 @sextw_sh2add(i1 zeroext %0, ptr %1, i32 signext %2, i32 signext %3, i32 signext %4) {
; RV64I-LABEL: sextw_sh2add:
; RV64I:       # %bb.0:
; RV64I-NEXT:    slli a2, a2, 2
; RV64I-NEXT:    add a3, a2, a3
; RV64I-NEXT:    beqz a0, .LBB22_2
; RV64I-NEXT:  # %bb.1:
; RV64I-NEXT:    sw a3, 0(a1)
; RV64I-NEXT:  .LBB22_2:
; RV64I-NEXT:    addw a0, a3, a4
; RV64I-NEXT:    ret
;
; RV64ZBB-LABEL: sextw_sh2add:
; RV64ZBB:       # %bb.0:
; RV64ZBB-NEXT:    sh2add a2, a2, a3
; RV64ZBB-NEXT:    beqz a0, .LBB22_2
; RV64ZBB-NEXT:  # %bb.1:
; RV64ZBB-NEXT:    sw a2, 0(a1)
; RV64ZBB-NEXT:  .LBB22_2:
; RV64ZBB-NEXT:    addw a0, a2, a4
; RV64ZBB-NEXT:    ret
;
; NOREMOVAL-LABEL: sextw_sh2add:
; NOREMOVAL:       # %bb.0:
; NOREMOVAL-NEXT:    sh2add a2, a2, a3
; NOREMOVAL-NEXT:    sext.w a2, a2
; NOREMOVAL-NEXT:    beqz a0, .LBB22_2
; NOREMOVAL-NEXT:  # %bb.1:
; NOREMOVAL-NEXT:    sw a2, 0(a1)
; NOREMOVAL-NEXT:  .LBB22_2:
; NOREMOVAL-NEXT:    addw a0, a2, a4
; NOREMOVAL-NEXT:    ret
  %6 = shl i32 %2, 2
  %7 = add i32 %6, %3
  br i1 %0, label %8, label %9

8:                                                ; preds = %5
  store i32 %7, ptr %1, align 4
  br label %9

9:                                                ; preds = %5, %8
  %10 = add i32 %7, %4
  ret i32 %10
}

; Negative test - an explicit sext.w *is* required
define signext i32 @test19(i64 %arg, i1 zeroext %c1, i1 zeroext %c2, ptr %p) nounwind {
; CHECK-LABEL: test19:
; CHECK:       # %bb.0: # %bb
; CHECK-NEXT:    addi sp, sp, -16
; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; CHECK-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
; CHECK-NEXT:    neg a0, a1
; CHECK-NEXT:    li a1, 1
; CHECK-NEXT:    slli a1, a1, 32
; CHECK-NEXT:    addi s0, a1, 35
; CHECK-NEXT:    and s0, a0, s0
; CHECK-NEXT:    sd s0, 0(a3)
; CHECK-NEXT:    beqz a2, .LBB23_2
; CHECK-NEXT:  # %bb.1: # %bb2
; CHECK-NEXT:    li a0, 0
; CHECK-NEXT:    call bar@plt
; CHECK-NEXT:    mv s0, a0
; CHECK-NEXT:  .LBB23_2: # %bb7
; CHECK-NEXT:    call side_effect@plt
; CHECK-NEXT:    sext.w a0, s0
; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; CHECK-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
; CHECK-NEXT:    addi sp, sp, 16
; CHECK-NEXT:    ret
;
; NOREMOVAL-LABEL: test19:
; NOREMOVAL:       # %bb.0: # %bb
; NOREMOVAL-NEXT:    addi sp, sp, -16
; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
; NOREMOVAL-NEXT:    neg a0, a1
; NOREMOVAL-NEXT:    li a1, 1
; NOREMOVAL-NEXT:    slli a1, a1, 32
; NOREMOVAL-NEXT:    addi s0, a1, 35
; NOREMOVAL-NEXT:    and s0, a0, s0
; NOREMOVAL-NEXT:    sd s0, 0(a3)
; NOREMOVAL-NEXT:    beqz a2, .LBB23_2
; NOREMOVAL-NEXT:  # %bb.1: # %bb2
; NOREMOVAL-NEXT:    li a0, 0
; NOREMOVAL-NEXT:    call bar@plt
; NOREMOVAL-NEXT:    mv s0, a0
; NOREMOVAL-NEXT:  .LBB23_2: # %bb7
; NOREMOVAL-NEXT:    call side_effect@plt
; NOREMOVAL-NEXT:    sext.w a0, s0
; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
; NOREMOVAL-NEXT:    addi sp, sp, 16
; NOREMOVAL-NEXT:    ret
bb:
  %sel = select i1 %c1, i64 4294967331, i64 0
  store i64 %sel, ptr %p, align 8
  br i1 %c2, label %bb2, label %bb7

bb2:                                              ; preds = %bb2, %bb
  %i4 = call signext i32 @bar(i32 0)
  %i4.sext = sext i32 %i4 to i64
  br label %bb7

bb7:                                              ; preds = %bb2
  %phi = phi i64 [ %sel, %bb ], [ %i4.sext, %bb2 ]
  %trunc = trunc i64 %phi to i32
  call void @side_effect()
  ret i32 %trunc
}

 declare void @side_effect(i64)
